package com.s7.compat.network.support;

import com.s7.compat.network.exception.ERROR;
import com.s7.compat.network.exception.ExceptionHandle;
import com.s7.compat.network.exception.ResponeThrowable;
import com.s7.compat.network.listener.OnRequestListener;
import com.s7.compat.type.typeimpl.ParameterizedTypeImpl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import io.reactivex.observers.DisposableObserver;
import okhttp3.ResponseBody;

public abstract class BaseObserver<T> extends DisposableObserver<ResponseBody> {

    protected OnRequestListener<T> listener;
    protected Type type;
    private boolean isEnd = false;

    public BaseObserver() {
        type = Object.class;
    }

    public BaseObserver(OnRequestListener<T> listener) {
        this.listener = listener;
        type = this.listener.tClass;
    }

    @Override
    public void onNext(ResponseBody body) {
        if (!isEnd) {
            onEnd();
        }
        onResponseBody(body);
    }

    protected abstract void onResponseBody(ResponseBody body);

    public Type[] getType() {
        if (!(type instanceof Class)) {
            Type mt = ((ParameterizedType) type).getActualTypeArguments()[0];
            Type listType = new ParameterizedTypeImpl(List.class, new Type[]{mt});
            return new Type[]{listType};
        } else {
            return new Type[]{type};
        }
    }

    protected void onSuccess(T data) {
        if (listener != null) {
            listener.onSuccess(data);
        }
    }

    protected void onUnusual(int code, String message) {
        if (listener != null) {
            listener.onError(new ResponeThrowable(code, message));
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        isEnd = false;
    }

    protected void onEnd() {
        isEnd = true;
    }

    protected void onCancel() {
        if (!this.isDisposed()) {
            this.dispose();
        }
    }

    @Override
    public void onError(Throwable e) {
        if (listener != null) {
            if(e instanceof Exception){
                if (listener != null) {
                    listener.onError(ExceptionHandle.handleException(e));
                }
            }else {
                if (listener != null) {
                    listener.onError(new ResponeThrowable(e, ERROR.UNKNOWN));
                }
            }
        }
        onEnd();
    }

    @Override
    public void onComplete() {
        if (!isEnd) {
            onEnd();
        }
    }

}

